package Model;

import javax.swing.JSlider;


@SuppressWarnings("serial")
public class TestVolume extends JSlider {
    float curFloat;
	private double minFloat, maxFloat;
    private boolean isLogScale;
    
    @Override
    protected void fireStateChanged() {
        int 
            ival = TestVolume.super.getValue(),
            min = TestVolume.super.getMinimum(),
            max = TestVolume.super.getMaximum();
        float dval = transformRange(false,      min,      max,  ival,
                                     isLogScale, minFloat, maxFloat);

        setFloatValue(dval);  
        super.fireStateChanged();
    }

    public TestVolume(int orientation, float cur, double min, double max, boolean log) {
        super(orientation);
        super.getModel().setRangeProperties(1, 1, 0, 100, false);
        super.setExtent(0);
        minFloat = min;
        maxFloat = max;
        curFloat = cur;
        isLogScale = log;
        setFloatValue(cur);
    }

    
    public TestVolume() {
		// TODO Auto-generated constructor stub
	}
    
    public TestVolume(int orientation, float cur, double min, double max) {
        this(orientation, cur, min, max, false);
    }

    protected int rangeValue(double dval) {
        dval = clamp(dval, minFloat, maxFloat);
        int 
            min = super.getMinimum(),
            max = super.getMaximum();
        //System.out.println("setting: dval="+dval+" -> ival="+ival);
        return (int)Math.round(transformRange(isLogScale, minFloat, maxFloat, dval, false, min, max));
    }

    public double getFloatMinimum() {
        return minFloat;
    }
    public double getFloatMaximum() {
        return maxFloat;
    }
    public float getFloatValue() {
        return curFloat;
    }

    public void setFloatMinimum(double newmin) {
        setAll(newmin, maxFloat, getFloatValue());
    }
    public void setFloatMaximum(double newmax) {
        setAll(minFloat, newmax, getFloatValue());
    }
    public void setFloatValue(float newcur) {

        curFloat = newcur;
        super.setValue(rangeValue(newcur));
    }

    public void setAll(double newmin, double newmax, float newcur) {
        minFloat = newmin;
        maxFloat = newmax;
        setFloatValue(newcur);
    }

    private static double clamp(double x, double a, double b)
    {
        return x <= a ? a :
               x >= b ? b : x;
    }
    private static double lerp(double a, double b, double t)
    {
        return a + (b-a) * t;
    }
    private static double gerp(double a, double b, double t)
    {
        return a * Math.pow(b/a, t);
    }

    private static float transformRange(boolean isLog, double a, double b, double x, boolean IsLog, double A, double B) {
        if (isLog)
        {
            a = Math.log(a);
            b = Math.log(b);
            x = Math.log(x);
        } 
        double t = (x-a) / (b-a);
        return (float) (IsLog ? gerp(A,B,t) : lerp(A,B,t));
    }
}
